package com.bdzl.api.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bdzl.pub.config.Constant;
import com.bdzl.pub.entity.data.BankcardDO;
import com.bdzl.pub.entity.data.EnterpriseDO;
import com.bdzl.pub.entity.data.UserInfoDO;
import com.qcloud.image.ImageClient;
import com.qcloud.image.exception.AbstractImageException;
import com.qcloud.image.exception.ParamException;
import com.qcloud.image.request.*;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author DK
 * @date 2019-01-14 19:26
 **/
public class QCloudOCRUtil {
    public static String appId = Constant.bdzl_tengxun_could_AppId;
    public static String AppSecret = Constant.bdzl_tengxun_could_AppSecret;
    public static String secretId = Constant.bdzl_tengxun_could_secretId;
    public static String secretKey = Constant.bdzl_tengxun_could_secretKey;
    public static String bucketName = Constant.bdzl_tengxun_could_bucket_name_OCR;
    private static final Logger logger = LoggerFactory.getLogger(QCloudOCRUtil.class);
    /**
     * 营业执照OCR
     *
     * @param url 营业执照图片地址
     * @return 营业执照信息
     * @throws AbstractImageException
     */
    public static String getBusinessMsg(String url) throws AbstractImageException {
        String request = JSON.toJSONString(url);
        //获取数据字典的描述
//        String note = SysDictUtil.getName(Constant.TXC__API_TYPE, "01");
        //将接口请求数据保存到数据库中
//        AutoApiUtils.saveJsonObject(Constant.TXC__API_TYPE, request, note);
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrBizLicense(new OcrBizLicenseRequest(bucketName, url));
        //将响应的信息保存到数据库中
//        AutoApiUtils.saveLogObject(Constant.TXC__API_TYPE, request, response, note);
        return response;

    }

    /**
     * 营业执照OCR
     *
     * @param file 营业执照图片文件
     * @return 营业执照信息
     * @throws AbstractImageException
     */
    public static String getBusinessMsg(File file) throws AbstractImageException {
        String request = null;
        //获取数据字典的描述
//        String note = SysDictUtil.getName(Constant.TXC__API_TYPE, "01");
        //将接口请求数据保存到数据库中
//        AutoApiUtils.saveJsonObject(Constant.TXC__API_TYPE, request, note);
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrBizLicense(new OcrBizLicenseRequest(bucketName, file));
        //将响应的信息保存到数据库中
//        AutoApiUtils.saveLogObject(Constant.TXC__API_TYPE, request, response, note);
        return response;
    }

    /**
     * OCR-银行卡识别
     *
     * @param url 银行卡图片地址
     * @return 银行卡信息
     * @throws AbstractImageException
     */
    public static String getBankCardMsg(String url) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrBankCard(new OcrBankCardRequest(bucketName, url));
        return response;
    }

    /**
     * OCR-银行卡识别
     *
     * @param file 银行卡图片文件
     * @return 银行卡信息
     * @throws AbstractImageException
     */
    public static String getBankCardMsg(File file) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrBankCard(new OcrBankCardRequest(bucketName, file));
        return response;
    }

    /**
     * 不能识别副页，别把副页拍上
     * OCR-行驶证驾驶证识别
     *
     * @param url 行驶证驾驶证图片地址
     * @return 行驶证驾驶证信息
     * @throws AbstractImageException
     */
    public static String getDrivingLicenceMsg(String url) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrDrivingLicence(new OcrDrivingLicenceRequest(bucketName, OcrDrivingLicenceRequest.TYPE_DRIVER_LICENSE, url));
        return response;
    }

    /**
     * 不能识别副页，别把副页拍上
     * OCR-行驶证驾驶证识别
     *
     * @param file 行驶证驾驶证图片文件
     * @return 行驶证驾驶证信息
     * @throws AbstractImageException
     */
    public static String getDrivingLicenceMsg(File file) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrDrivingLicence(new OcrDrivingLicenceRequest(bucketName, OcrDrivingLicenceRequest.TYPE_DRIVER_LICENSE, file));
        return response;
    }

    /**
     * OCR-车牌识别
     *
     * @param url 车牌图片地址
     * @return 车牌信息
     * @throws AbstractImageException
     */
    public static String getPlateMsg(String url) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrPlate(new OcrPlateRequest(bucketName, url));
        return response;
    }

    /**
     * OCR-车牌识别
     *
     * @param file 车牌图片文件
     * @return 车牌信息
     * @throws AbstractImageException
     */
    public static String getPlateMsg(File file) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.ocrPlate(new OcrPlateRequest(bucketName, file));
        return response;
    }

    /**
     * OCR-身份证识别
     *
     * @param url  身份证图片地址数组
     * @param type 身份证图片地址数组 0：数组图片识别正面，1：识别反面
     * @return 身份证信息
     * @throws AbstractImageException
     */
    public static String getIdCardMsg(String[] url, int type) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.idcardDetect(new IdcardDetectRequest(bucketName, url, type));
        return response;
    }

    /**
     * OCR-身份证识别
     *
     * @param file 身份证图片文件
     * @param type 身份证图片文件数组 0：数组图片识别正面，1：识别反面
     * @return 身份证信息
     * @throws AbstractImageException
     */
    public static String getIdCardMsg(File[] file, int type) throws AbstractImageException {
        ImageClient imageClient = new ImageClient(appId, secretId, secretKey, ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com);
        String response = imageClient.idcardDetect(new IdcardDetectRequest(bucketName, file, type));
        return response;
    }

    /**
     * Json转实体类
     * 营业执照OCR
     *
     * @param url 营业执照图片地址
     * @return 营业执照信息
     * @throws AbstractImageException
     */
    public static EnterpriseDO getBusinessLicense(String url) throws AbstractImageException {
        return getAnalysisBusinessLicenseJson(getBusinessMsg(url));
    }

    /**
     * Json转实体类
     * 营业执照OCR
     *
     * @param file 营业执照图片文件
     * @return 营业执照信息
     * @throws AbstractImageException
     */
    public static EnterpriseDO getBusinessLicense(File file) throws AbstractImageException {
        return getAnalysisBusinessLicenseJson(getBusinessMsg(file));
    }

    /**
     * Json转实体类
     * OCR-银行卡识别
     *
     * @param url 银行卡图片地址
     * @return 银行卡信息
     * @throws AbstractImageException
     */
    public static BankcardDO getBankCard(String url) throws AbstractImageException {
        return getAnalysisBankCardJson(getBankCardMsg(url));
    }

    /**
     * Json转实体类
     * OCR-银行卡识别
     *
     * @param file 银行卡图片文件
     * @return 银行卡信息
     * @throws AbstractImageException
     */
    public static BankcardDO getBankCard(File file) throws AbstractImageException {
        return getAnalysisBankCardJson(getBankCardMsg(file));
    }


    @Nullable
    private static EnterpriseDO getAnalysisBusinessLicenseJson(String businessMsg) {
        String response = businessMsg;
        Map<String, Object> responseMap = JSONObject.parseObject(response);
        String code = String.valueOf(responseMap.get("code"));
        if ("0".equals(code)) {
            String data = String.valueOf(responseMap.get("data"));
            Map<String, Object> dataMap = JSONObject.parseObject(data);
            String items = String.valueOf(dataMap.get("items"));
            List list = JSONObject.parseArray(items);
            List<Map<String, Object>> itemsList = new ArrayList<>(list);
            EnterpriseDO enterpriseDO = new EnterpriseDO();
            for (Map<String, Object> map : itemsList) {
                String item = String.valueOf(map.get("item"));
                String itemstring = String.valueOf(map.get("itemstring"));
                if ("注册号".equals(item)) {
                    enterpriseDO.setEntNo(itemstring);
                } else if ("公司名称".equals(item)) {
                    enterpriseDO.setEntName(itemstring);
                } else if ("主体类型".equals(item)) {
                    enterpriseDO.setEntType(itemstring);
                } else if ("地址".equals(item)) {
                    enterpriseDO.setEntAdr(itemstring);
                } else if ("法定代表人".equals(item)) {
                    enterpriseDO.setEntLegal(itemstring);
                } else if ("注册资本".equals(item)) {
                    enterpriseDO.setEntMoney(itemstring);
                } else if ("营业期限".equals(item)) {
                    enterpriseDO.setEntBuslimit(itemstring);
                } else if ("经营范围".equals(item)) {
                    enterpriseDO.setEntScope(itemstring);
                }
            }
            return enterpriseDO;
        }
        return null;
    }

    @Nullable
    private static BankcardDO getAnalysisBankCardJson(String bankCardMsg) {
        String response = bankCardMsg;
        Map<String, Object> responseMap = JSONObject.parseObject(response);
        String code = String.valueOf(responseMap.get("code"));
        if ("0".equals(code)) {
            String data = String.valueOf(responseMap.get("data"));
            Map<String, Object> dataMap = JSONObject.parseObject(data);
            String items = String.valueOf(dataMap.get("items"));
            List list = JSONObject.parseArray(items);
            List<Map<String, Object>> itemsList = new ArrayList<>(list);
            BankcardDO bankCard = new BankcardDO();
            for (Map<String, Object> map : itemsList) {
                String item = String.valueOf(map.get("item"));
                String itemstring = String.valueOf(map.get("itemstring"));
                if ("卡号".equals(item)) {
                    bankCard.setBcNo(itemstring);
                } else if ("卡类型".equals(item)) {
                    bankCard.setBcType(itemstring);
                } else if ("卡名字".equals(item)) {
                    bankCard.setBcName(itemstring);
                } else if ("银行信息".equals(item)) {
                    bankCard.setBcBank(itemstring);
                } else if ("有效期".equals(item)) {
                    bankCard.setBcValidDate(itemstring);
                }
            }
            return bankCard;
        }
        return null;
    }

    /**
     * json 转 车牌号实体类
     *
     * @param url
     * @return
     * @throws AbstractImageException
     */
    /*public static CarPlateDo getCarPlateDo(String url) throws AbstractImageException {
        String jsonstr = getPlateMsg(url);
        return newInstanceCarPlateDo(jsonstr);
    }*/

    /**
     * json 转 车牌号实体类
     *
     * @param file
     * @return
     * @throws AbstractImageException
     */
    /*public static CarPlateDo getCarPlateDo(File file) throws AbstractImageException {
        String jsonstr = getPlateMsg(file);
        return newInstanceCarPlateDo(jsonstr);
    }*/

    /**
     * json封装车牌号实体类
     *
     * @param
     * @return
     */
    /*private static CarPlateDo newInstanceCarPlateDo(String jsonstr) {
        //
        JSONObject objjson = JSONObject.parseObject(jsonstr);
        String code = objjson.getString("code");//取出code
        if ("0".equals(code)) {
            String message = objjson.getString("message");//取出信息
            String arraystr = objjson.getString("data");//取出items
            Map items = JSONObject.parseObject(arraystr);//取出items

            List listarray = (List) items.get("items");

            Map item = (Map) listarray.get(0);

            String itemstring = String.valueOf(item.get("itemstring"));
            CarPlateDo cardo = new CarPlateDo(code, message, itemstring);
            return cardo;
        }

        return null;
    }*/

    /**
     * json 转 身份证实体类
     *
     * @param files
     * @param type
     * @param iDDos
     * @return
     * @throws AbstractImageException
     */
    public static void getIDDos(File files[], int type, List<UserInfoDO> iDDos) throws AbstractImageException {

        if (type == 1) {//反面
            String jsonstr = getIdCardMsg(files, 1);
            getOpposite(jsonstr, iDDos);
        } else if (type == 0) {//正面
            String jsonstr = getIdCardMsg(files, 0);
            getPositive(jsonstr, iDDos);
        } else {
            new RuntimeException("type:0(身份证正面)，type:1(反面)else(Exception)").printStackTrace();
        }

    }




    /**
     * json 转 身份证实体类
     *
     * @param urls
     * @param type
     * @param userInfoDOList
     * @return
     * @throws AbstractImageException
     */
    public static void getIDDos(String urls[], int type, List<UserInfoDO> userInfoDOList) throws AbstractImageException {

        if (type == 1) {//反面
            String jsonstr = getIdCardMsg(urls, 1);
            logger.info("OCR身份证反面,返回JSON[{}]", jsonstr);
            getOpposite(jsonstr, userInfoDOList);
        } else if (type == 0) {//正面
            String jsonstr = getIdCardMsg(urls, 0);
            logger.info("OCR身份证正面,返回JSON[{}]", jsonstr);
            getPositive(jsonstr, userInfoDOList);
        } else {
           throw new RuntimeException("type:0(身份证正面)，type:1(反面)else(Exception)");
        }

    }

    /**
     * json 转 身份证实体类
     *
     * @param file
     * @param type
     * @param userInfoDOList
     * @return
     * @throws AbstractImageException
     */
    public static void getIDDos(File file, int type, List<UserInfoDO> userInfoDOList) throws AbstractImageException {
        File[] files = new File[]{file};
        getIDDos(files, type, userInfoDOList);
    }

    /**
     * 获取身份证反面数据。数据封装到参数》iDDos里
     *
     * @return
     */
    private static void getOpposite(String jsonstr, List<UserInfoDO> userInfoDOList) throws ParamException {

        if (userInfoDOList == null) {
            new RuntimeException("参数userInfoDOList不能==null").printStackTrace();
            return;
        }
        Map map = JSONObject.parseObject(jsonstr);
        System.out.println(map);
        String resultList = String.valueOf(map.get("result_list"));
        System.out.println(">>>>>>" + resultList + ">>>>>");

        List list = (List) JSONObject.parse(resultList);
        System.out.println(list);
        // List<Map<String,Object>>mapList = new ArrayList<>(items);
        for (int i = 0; i < list.size(); i++) {
            map = (Map) list.get(i);
            Integer code = Integer.parseInt(map.get("code").toString());
            if (0 == code) {
                Map m = (Map) map.get("data");
                String authority = (String) m.get("authority");
                String valid_date = (String) m.get("valid_date");
                if (userInfoDOList.isEmpty()) {
                    UserInfoDO userInfoDO = new UserInfoDO();
                    /*userInfoDO.setAuthority(authority);
                    userInfoDO.setValid_date(valid_date);*/
                    userInfoDOList.add(userInfoDO);
                } else {
                    if (userInfoDOList.size() == list.size()) {
                        UserInfoDO userInfoDO = userInfoDOList.get(i);
                        /*userInfoDO.setAuthority(authority);
                        userInfoDO.setValid_date(valid_date);*/
                    } else {
                       throw  new RuntimeException("身份证数量和，list个数要对应");
                    }
                }
            }else{
                throw new ParamException("身份证识别失败");
            }

        }

    }

    /**
     * 获取正面数据,数据封装到参数》iDDos里
     *
     * @param jsonstr
     * @param userInfoDOList
     */
    private static void getPositive(String jsonstr, List<UserInfoDO> userInfoDOList) throws ParamException {
        if (userInfoDOList == null) {
            throw new RuntimeException("参数userInfoDOList不能==null");
        }
        Map map = JSONObject.parseObject(jsonstr);
        System.out.println(map);
        String resultList = String.valueOf(map.get("result_list"));
        List list = (List) JSONObject.parse(resultList);
        logger.info("result_list [{}]",list);
        for (int i = 0; i < list.size(); i++) {
            map = (Map) list.get(i);
            Integer code = Integer.parseInt(map.get("code").toString());
            logger.info("ocr 状态码： {}",code);
            logger.info("ocr 状态码比较： {}",Integer.compare(0 , code) == 0);
            if (Integer.compare(0 , code) == 0) {
                Map m = (Map) map.get("data");
                String name = (String) m.get("name");
                String sex = (String) m.get("sex");
                String nation = (String) m.get("nation");
                String birth = (String) m.get("birth");
                String address = (String) m.get("address");
                String id = (String) m.get("id");

                if (userInfoDOList.isEmpty()) {
                    UserInfoDO userInfoDO = new UserInfoDO();
                    userInfoDO.setConName(name);
                    userInfoDO.setConSex(sex);
                    userInfoDO.setConNation(nation);
                    userInfoDO.setConCardid(id);
                    userInfoDO.setConCardAdr(address);
                    userInfoDO.setConBirth(birth);
                    userInfoDOList.add(userInfoDO);
                } else {
                    if (userInfoDOList.size() == list.size()) {
                        UserInfoDO userInfoDO = userInfoDOList.get(i);
                        userInfoDO.setConName(name);
                        userInfoDO.setConSex(sex);
                        userInfoDO.setConNation(nation);
                        userInfoDO.setConCardid(id);
                        userInfoDO.setConCardAdr(address);
                        userInfoDO.setConBirth(birth);
                    } else {
                       throw  new RuntimeException("身份证数量和，list个数要一一对应");
                    }
                }
            }else{
                throw new ParamException("身份证识别失败");
            }
        }
    }


    /**
     * 字符串转日期
     *
     * @param strDate
     * @return
     */
    private static Date toDate(String strDate, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date d = null;
        try {
            d = sdf.parse(strDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return d;
    }

    /**
     * 封装json数据》到行驶证实体类
     *
     * @param jsonstr
     * @return
     */
   /* private static DrivingLicense newInstanceDriving(String jsonstr) {

        Map maps = JSONObject.parseObject(jsonstr);
        String code = String.valueOf(maps.get("code"));
        if ("0".equals(code)) {
            DrivingLicense drivingLicense = new DrivingLicense();
            Map map = (Map) maps.get("data");
            List items = JSONObject.parseArray(String.valueOf(map.get("items")));
            List<Map<String, Object>> mapList = new ArrayList<>(items);
            for (Map<String, Object> map1 : mapList) {
                String type = (String) map1.get("item");
                if ("证号".equals(type)) {
                    drivingLicense.setId((String) map1.get("itemstring"));
                } else if ("姓名".equals(type)) {
                    drivingLicense.setName((String) map1.get("itemstring"));
                } else if ("性别".equals(type)) {
                    drivingLicense.setSex((String) map1.get("itemstring"));
                } else if ("国籍".equals(type)) {
                    drivingLicense.setNationality((String) map1.get("itemstring"));
                } else if ("住址".equals(type)) {
                    drivingLicense.setAddress((String) map1.get("itemstring"));
                } else if ("出生日期".equals(type)) {
                    drivingLicense.setBrith((String) map1.get("itemstring"));
                } else if ("领证日期".equals(type)) {
                    drivingLicense.setCerDate((String) map1.get("itemstring"));
                } else if ("准驾车型".equals(type)) {
                    drivingLicense.setType((String) map1.get("itemstring"));
                } else if ("起始日期".equals(type)) {
                    drivingLicense.setStartDate((String) map1.get("itemstring"));
                } else if ("有效日期".equals(type)) {
                    drivingLicense.setValidDate((String) map1.get("itemstring"));
                } else if ("红章".equals(type)) {
                    drivingLicense.setChapter((String) map1.get("itemstring"));
                }
            }

            return drivingLicense;
        } else {
            return null;
        }

    }*/

    /**
     * json转DrivingLicense行驶证实体类
     *
     * @param url
     * @return
     * @throws AbstractImageException
     */
    /*public static DrivingLicense getDriving(String url) throws AbstractImageException {
        String jsonstr = getDrivingLicenceMsg(url);
        return newInstanceDriving(jsonstr);
    }*/

    /**
     * json转DrivingLicense行驶证实体类
     *
     * @param file
     * @return
     * @throws AbstractImageException
     */
    /*public static DrivingLicense getDriving(File file) throws AbstractImageException {
        String jsonstr = getDrivingLicenceMsg(file);
        return newInstanceDriving(jsonstr);
    }*/

}
